import {
  ParamArr
} from './paramarr'
import Global from './global'
import {
  Message
} from 'element-ui'

export default class CreateWebSocket {
  constructor(p) {
    // 全部请求回调方法 id => function
    this.funcMap = new Map()
    // 最后一次完成通讯的时间
    this.lastSuccessTime
    // 检查连接延时器
    this.checkTimer
    // 重连的定时器
    this.reConnectTimer
    this.url = (location.protocol === 'http:' ? 'ws://' : 'wss//') + location.host
    this.IDD_IsSocket = '{8B8C08DD-CD0D-4F3C-8440-4C271D701FCF}'

    if (globalConfig.url) {
      this.url = globalConfig.url
    }
    this.msgLstObject = []
    // 提示框返回的关闭对象
    this.messageBoxRes = null
    // 当前连接是否有错误
    this.isConnectError = false
    this.init()
  }
  // 消息推送需要处理的函数数组
  init = function () {
    if (!(window.WebSocket || window.MozWebSocket)) {
      return this.showMsgBox('警告：当前浏览器不支持WebSocket', 'error')
    }
    try {
      if (this.ws) this.ws.close()
      this.ws = new WebSocket(this.url)
      this.initWs()
    } catch (e) {
      console.error(e)
      this.reConnect()
    }
  }
  // 初始化socket的方法
  initWs = function () {
    const _this = this
    this.ws.onopen = function () {
      _this.lastSuccessTime = new Date().getTime()
      _this.checkConnect()
      _this.login()
    }
    this.ws.onmessage = function (e) {
      _this.lastSuccessTime = new Date().getTime()
      try {
        var data = JSON.parse(e.data)
        var guid = data.response.id
        var func = _this.funcMap.get(guid)
        data[_this.IDD_IsSocket] = true
        var vRst = new ParamArr(data)
        if (func) {
          func(vRst, vRst.getReturn())
          _this.funcMap.delete(guid)
        }
        if (top.mainMessages && vRst.getMsgId() !== 1) {
          top.mainMessages.getMessages(vRst, vRst.getReturn())
        }
      } catch (error) {
        console.error(error)
      }
    }

    this.ws.onerror = function () {
      _this.reConnect()
    }

    this.ws.onclose = function () {
      _this.reConnect()
    }
  }

  // 检查连接
  checkConnect = function () {
    const _this = this
    clearTimeout(_this.checkTimer)
    this.checkTimer = setTimeout(function () {
      if ((new Date().getTime() - _this.lastSuccessTime) > 15000) {
        _this.showMsgBox('您的网络连接有问题', 'error', 30000)
        _this.isConnectError = true
        return
      }
      _this.callServerFuncSocket('Ws', 'Ping')
      _this.checkConnect()
    }, 5000)
  }

  // 重新连接
  reConnect = function () {
    const _this = this
    clearTimeout(this.reConnectTimer)
    this.reConnectTimer = setTimeout(function () {
      _this.showMsgBox('正在重新连接...', 'warning', 30000)
      _this.init()
    }, 2000)
  }

  login = function () {
    const _this = this
    // 保存当前用户信息 用于重连
    _this.eds = sessionStorage.getItem('eds') || ''
    _this.deskey = sessionStorage.getItem('deskey') || ''
    _this.user = sessionStorage.getItem('user') || ''
    if (_this.user !== '' && _this.eds !== '' && _this.deskey !== '') {
      let pass = Global.decryptByDESModeEBC(_this.eds, _this.deskey)
      var vPar = new ParamArr()
      vPar.setStr('User', _this.user)
      vPar.setStr('Pass', Global.MD5(pass))
      vPar.setStr('PassDES', Global.desEtStr(pass))
      vPar.setStr('SavePass', vPar.getStr('Pass'))
      vPar.setStr('SavePassDES', vPar.getStr('PassDES'))
      this.callServerFuncSocket('TCoreDM', 'SetWsControl', vPar, function (vPar, sError) {
        if (sError) return _this.showMsgBox(sError, 'error')
        top.mainMessages.regWebJsonMessage()
        if (_this.isConnectError) {
          _this.isConnectError = false
          _this.showMsgBox('连接成功', 'success')
        }
      })
    } else {
      setTimeout(function(){
        _this.login()
      }, 1000);
    }
  }

  /**
   * @description  socket 方式发送请求
   * @param {Object} md   请求模块名称
   * @param {Object} mt   请求方法名称
   * @param {Object} vPar 请求的参数数据(和以前一样)
   * @param {Object} lpfCallback 回调
   */
  callServerFuncSocket = function (md, mt, vPar, lpfCallback) {
    vPar = vPar || new ParamArr()
    var guid = Global.getGuid()
    var data = {}
    // 请求信息
    var request = {
      method: mt,
      module: md,
      id: guid
    }
    // 参数信息
    var body = {}
    var dataArr = JSON.parse(vPar.toJson(true))
    for (var i = 0; i < dataArr.length; i++) {
      body[dataArr[i].Name] = dataArr[i].Value
    }
    data.request = request
    data.body = body
    // 保存回调方法
    if (typeof (lpfCallback) === 'function') this.funcMap.set(guid, lpfCallback)
    this.ws.send(JSON.stringify(data))
  }

  showMsgBox = function (msg, type, time) {
    time = time === 0 ? 0 : (time || 3000)
    if (this.messageBoxRes) this.messageBoxRes.close()
    this.messageBoxRes = Message({
      message: msg,
      type: type,
      duration: time
    })
  }

  closeMsgBox = function () {
    if (this.messageBoxRes) this.messageBoxRes.close()
  }
}
